﻿namespace Microsoft.SharePoint.Client
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Diagnostics;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Reflection;
    using System.Runtime.CompilerServices;

    public abstract class ClientObjectCollection<T> : ClientObjectCollection, IQueryable<T>, IEnumerable<T>, IQueryable, IEnumerable
    {
        private ClientObjectPrototype<T> m_itemPrototype;

        public ClientObjectCollection(ClientRuntimeContext context, ObjectPath objectPath) : base(context, objectPath)
        {
        }

        internal override void CleanupQuery()
        {
            base.CleanupQuery();
            this.m_itemPrototype = null;
        }

        [EditorBrowsable(EditorBrowsableState.Never)]
        public ClientObjectPrototype<T> RetrieveItems()
        {
            if (this.m_itemPrototype == null)
            {
                this.m_itemPrototype = new ClientObjectPrototype<T>(base.Query, true);
            }
            return this.m_itemPrototype;
        }

        IEnumerator<T> IEnumerable<T>.GetEnumerator()
        {
            this.ThrowIfCollectionNotInited();
            int count = this.Count;
            int i = 0;
            while (true)
            {
                if (i >= this.Count)
                {
                    yield break;
                }
                if (count != this.Count)
                {
                    throw new InvalidOperationException(Resources.GetString("CollectionModified"));
                }
                yield return (T) this.GetItemAtIndex(i);
                i++;
            }
        }

        public Type ElementType
        {
            get
            {
                return typeof(T);
            }
        }

        public System.Linq.Expressions.Expression Expression
        {
            get
            {
                return System.Linq.Expressions.Expression.Constant(this);
            }
        }

        public T this[int index]
        {
            get
            {
                base.ThrowIfCollectionNotInited();
                return (T) base.GetItemAtIndex(index);
            }
        }

        public IQueryProvider Provider
        {
            get
            {
                return base.Context.QueryProvider;
            }
        }

        //[CompilerGenerated]
        //private sealed class GetEnumerator>d__0 : IEnumerator<T>, IEnumerator, IDisposable
        //{
        //    private int <>1__state;
        //    private T <>2__current;
        //    public ClientObjectCollection<T> <>4__this;
        //    public int <i>5__2;
        //    public int <originalCount>5__1;

        //    [DebuggerHidden]
        //    public GetEnumerator>d__0(int <>1__state)
        //    {
        //        this.<>1__state = <>1__state;
        //    }

        //    private bool MoveNext()
        //    {
        //        switch (this.<>1__state)
        //        {
        //            case 0:
        //                this.<>1__state = -1;
        //                this.<>4__this.ThrowIfCollectionNotInited();
        //                this.<originalCount>5__1 = this.<>4__this.Count;
        //                this.<i>5__2 = 0;
        //                break;

        //            case 1:
        //                this.<>1__state = -1;
        //                this.<i>5__2++;
        //                break;

        //            default:
        //                goto Label_00B6;
        //        }
        //        if (this.<i>5__2 < this.<>4__this.Count)
        //        {
        //            if (this.<originalCount>5__1 != this.<>4__this.Count)
        //            {
        //                throw new InvalidOperationException(Resources.GetString("CollectionModified"));
        //            }
        //            this.<>2__current = (T) this.<>4__this.GetItemAtIndex(this.<i>5__2);
        //            this.<>1__state = 1;
        //            return true;
        //        }
        //    Label_00B6:
        //        return false;
        //    }

        //    [DebuggerHidden]
        //    void IEnumerator.Reset()
        //    {
        //        throw new NotSupportedException();
        //    }

        //    void IDisposable.Dispose()
        //    {
        //    }

        //    T IEnumerator<T>.Current
        //    {
        //        [DebuggerHidden]
        //        get
        //        {
        //            return this.<>2__current;
        //        }
        //    }

        //    object IEnumerator.Current
        //    {
        //        [DebuggerHidden]
        //        get
        //        {
        //            return this.<>2__current;
        //        }
        //    }
        //}
    }
}

